#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include <net/if.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <linux/can.h>
#include <linux/can/raw.h>

#include "dataqueue.h"
extern Cthread_canworkqueue * canrecvqueue;   //can接收队列结构体


/**********************
 *  创建初始化can接口
 * 参数：
 * 		name：can0 或者 can1
 * return：
 * 		套接字句柄
 *
 * *******************/
int canbus_init(void)
{
	int s;	//套接字返回句柄
	struct sockaddr_can addr;

	struct ifreq ifr;	

	//创建socket
	if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
		perror("Error while creating CAN:socket");
		return -1;
	}
	
	strcpy(ifr.ifr_name, "can1");
    if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
        perror("ioctl failed");
        return -1;
    }
	
	addr.can_family  = PF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;

//	setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); //禁用过滤器

	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { //绑定套接字 就是 套接字和canbus外设进行绑定
		perror("bind failed!");
		return -1;
	}
    //printf("Can0 init successfully!\r\n"); 

	return s;
}


/***************************************
 * can发送数据
 * arg：	fd：套接字句柄
 * 			id：can id，标准id
 * 			data：要传输的数据指针
 * 			len：数据长度
 * return：发送的字节数
 * 
 * ************************************/
int canbus_send(int fd,unsigned int id, char *data, unsigned int len)
{
	int i,ret;

	struct can_frame frame;

	if((id > 0x7ff) || (len > 8)){
		perror("canbus id or data len error!");
        return -1;
	}

	frame.can_id = (canid_t)id;
	frame.can_dlc = len;
	for(i = 0; i < len; i++)
		frame.data[i] = data[i];
	
	ret = write(fd,&frame,sizeof(frame));
	if(ret < 0){
		perror("data write error!");
	}

	return ret;

}

/***************************************
 * can接收数据
 * arg：	fd：套接字句柄
 * 			id：can id，标准id
 * 			data：要传输的数据指针
 * 			len：数据长度
 * return：发送的字节数
 * 
 * ************************************/
int canbus_recv(const int fd)
{
	int len,i;
	struct can_frame buff;
	CANTxMsg_t rxmsg;	
	//printf("can receive data!\n");
	len = read(fd,&buff,sizeof(buff));
	if( len == sizeof(buff))
	{
		rxmsg.CANTxStruct.StdId = buff.can_id;
		rxmsg.CANTxStruct.DLC = buff.can_dlc;
		for( i = 0 ; i < buff.can_dlc ; i++)
		{
			rxmsg.CANTxStruct.Data[i] = buff.data[i];
			//printf("%x ",buff.data[i]);
			
		}
		//printf("\n");
		can_add_task(canrecvqueue,&rxmsg); //添加接收到的数据到接收队列，等待制定线程处理哦
	}else{
		printf("CAN receive error!!!\n");
		return -1; //接收错误
	}

	return 0;
	
}

